/*************************************************************************
	> File Name: 003.LinkList.c
	> Author: Maureen 
	> Mail: Maureen@qq.com 
	> Created Time: 三  9/ 1 16:00:47 2021
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct ListNode {
    int data;
    struct ListNode *next; 
} ListNode;

typedef struct List {
    ListNode head;
    int length;
} List;

/*
 * 链表结点的初始化
 */
ListNode *getNewNode(int val) {
    ListNode *node = (ListNode *)malloc(sizeof(ListNode));
    node->data = val;
    node->next = NULL;
    return node;
}

/*
 * 链表的初始化
 */
List *getLinkList() {
    List *l = (List *)malloc(sizeof(List));
    l->head.next = NULL;
    l->length = 0;
    return l;
}

/*
 * 链表结点的插入
 */
int insert(List *l, int ind, int val) {
    if (l == NULL) 
        return -1;
    if (ind < 0 || ind > l->length) 
        return -1;
    ListNode *node = getNewNode(val);
    ListNode *p = &(l->head);
    while (ind--) { //找到待插入位置的前一个位置
        p = p->next;
    }
    node->next = p->next;
    p->next = node;
    l->length++;
    return 0;
} 


/*
 * 链表结点的删除
 */
int erase(List *l, int ind) {
    if (l == NULL)
        return -1;
    if (ind < 0 || ind >= l->length) 
        return -1;
    ListNode *p = &(l->head);
    while (ind--) {
        p = p->next;
    }
    ListNode *temp = p->next;
    p->next = temp->next;
    free(temp);
    l->length--;
    return 0;
}

/*
 * 链表结点的打印
 */
void output(List *l) {
    if (l == NULL) return ;
    printf("List(%d) = [", l->length);
    for (ListNode *p = l->head.next; p; p = p->next) {
        printf("%d->", p->data);
    }
    printf("NULL]\n");
    return ;
}

/*
 * 链表结点的销毁
 */
void clear_node(ListNode *node) {
   if (node == NULL) return ;
    free(node);
    return ;
}

/*
 * 链表的销毁
 */
void clear(List *l) {
    if (l == NULL) return ;
    ListNode *p = l->head.next;
    ListNode *q;
    while (p) {
        q = p->next;
        clear_node(p);
        p = q;
    }
    free(l);
    return ;
}

int main() {
    srand(time(0));
    #define max_op 20
    List *l = getLinkList();
    for (int i = 0; i < max_op; i++) {
        int val = rand() % 100;
        int ind = rand() % (l->length + 3) - 1;
        int op = rand() % 4;
        switch (op) {
            case 0:
            case 1:
            case 2: {
                printf("insert %d at %d to List, result = %d\n", val, ind, insert(l, ind, val));
            } break;
            case 3: {
                printf("erase an item at %d from List, result = %d\n", ind, erase(l, ind));
            } break;
        }
        output(l);
        printf("\n");
    }
    clear(l);
    #undef max_op
    return 0;
}

